// $codepro.audit.disable numericLiterals
/**
 * tests package
 */
package javamonsters.tests;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.awt.Point;
import java.math.BigDecimal;
import java.util.Map;

import javamonsters.model.Character;
import javamonsters.model.InventoryItem;
import javamonsters.model.Marketplace;
import javamonsters.model.Ship;
import javamonsters.model.SolarSystem;
import javamonsters.model.TradeGood;
import javamonsters.model.Ship.ShipType;
import javamonsters.model.SolarSystem.Attributes;
import javamonsters.model.SolarSystem.TechLevels;


import org.junit.Before;
import org.junit.Test;

/**
 * This tests non-trivial methods inside Marketplace
 * @author jham9
 * @author walker
 * @version 1.1
 */
public class MarketplaceTest {
	
	/**
	 * parent system 
	 */
	private SolarSystem parentSystem;
	
	/**
	 * marketplace
	 */
	private Marketplace market;

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void prepare() {
		parentSystem = new SolarSystem("system", new Point(100, 100),
				TechLevels.HI_TECH, Attributes.LOTS_OF_WATER);
		market = new Marketplace(parentSystem.getPlanets().get(0));
		market.setAssociatedShip(new Ship(ShipType.FLEA));
		market.setCurrentCharacter(new Character("Test", 4, 4, 4, 4,
				new BigDecimal(1000000), market.getAssociatedShip(), "Easy"));
	}

	/**
	 * Walker's junit test sell method
	 */
	@Test // $codepro.audit.disable disallowTestAnnotation
	public void testSell() {
		final TradeGood tg = TradeGood.FIREARMS;
		final int qty = 2;
		final int price = 10;
		//market.getAssociatedShip().addCargo(tg, qty);
		// quantity not implemented ><
		market.getAssociatedShip().addCargo(tg, 1);
		market.getAssociatedShip().addCargo(tg, 1);
		market.getSellMap().put(tg,
				new InventoryItem(new BigDecimal(price), qty));
		final Map<TradeGood, Integer> cargo =
				market.getAssociatedShip().getCargoContents();
		
		assertTrue("Cargo should contain 1 tradegood", cargo.size() == 1);
		assertTrue("Cargo should contain the designated tradegood",
				cargo.containsKey(tg));
		assertTrue("Cargo should have quantity 2 of designated tradegood",
				cargo.get(tg) == 2);
		market.sell(tg, 1);
		assertTrue("Cargo should have quantity 1 of designated tradegood",
				cargo.get(tg) == 1);
		market.sell(tg, 1);
		assertTrue("Cargo should not contain designated tradegood",
				cargo.get(tg) == null);
		
		// No error should be thrown with this line
		market.sell(tg, 1);
	}

	/**
	 * john ham's junit test method
	 */
	@Test // $codepro.audit.disable disallowTestAnnotation
	public void testBuy() {
		parentSystem = new SolarSystem("system", new Point(100, 100),
				TechLevels.HI_TECH, Attributes.LOTS_OF_WATER);
		market = new Marketplace(parentSystem.getPlanets().get(0));
		
		market.getBuyMap().put(TradeGood.WATER, new InventoryItem(
				new BigDecimal(50), 10));
		market.setAssociatedShip(new Ship(ShipType.FLEA));
		//market.getAssociatedShip().addCargo(TradeGood.MEDICINE, 1);
		market.setCurrentCharacter(new Character("Test", 4, 4, 4, 4,
				new BigDecimal(1000000), market.getAssociatedShip(), "Easy"));
		
		System.out.println(market.getAssociatedShip().getCargoContents().size());
		
		final int quantity = 1;
		final TradeGood good = TradeGood.WATER;
		
		market.buy(good, quantity);
		System.out.println(market.getAssociatedShip().getCargoContents().size());
		assertTrue("Good that was bought is only good in player's hull",
				market.getAssociatedShip().getCargoContents().size() == 1);
		
		// TODO: check conditional where good is already in the hull
		market.buy(good, quantity);
		assertTrue("Good that was bought is the second good of its kind in the hull",
				market.getAssociatedShip().getCargoContents().get(good) == 2);
	
		market.getCharacter().removeCredits(market.getCharacter().getCredits());
		
		market.buy(good, quantity);
		final BigDecimal goodPrice = market.getBuyMap().get(good).getPrice();
		
		assertFalse("Good is already in hull, but cannot be bought because " +
				"of insufficient credits", goodPrice.compareTo(
						market.getCharacter().getCredits()) <= 0);
		
		market.getAssociatedShip().removeCargo(good, 2);
		assertFalse("Good is not in hull, cannot be bought because " +
				"of insufficient credits", goodPrice.compareTo(
						market.getCharacter().getCredits()) <= 0);
	}
	
	/**
	 * @return String representation of buy test
	 */
	public String toString() {
		return "marketplace test";
	}

}
